﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using OhioState.AssetManaged;

namespace OhioState.Graphics
{
    [Serializable()]
    public sealed class FrameBufferObjectProxy : SharedAsset, IFrameBufferObject
    {
        #region Public Properties
        public IDepthBuffer DepthBuffer { get; private set; }

        public FrameBufferClear ClearFlags { get; private set; }

        public IList<ITexture> Textures
        {
            get { return new ReadOnlyCollection<ITexture>(textures); }
        }
        #endregion

        #region Constructors
        public FrameBufferObjectProxy(string name, ICollection<ITexture> textures)
            : this(name, textures, null, FrameBufferClear.Color)
        {
        }

        public FrameBufferObjectProxy(string name, ICollection<ITexture> textures, IDepthBuffer depthBuffer, FrameBufferClear clearFlags)
            : base(name)
        {
            this.textures = new List<ITexture>(textures.Count);
            foreach (ITexture texture in textures)
            {
                this.textures.Add(texture);
            }
            this.DepthBuffer = depthBuffer;
            this.ClearFlags = clearFlags;
            ValidateBufferFormats();
        }

        public FrameBufferObjectProxy(string name, ITexture texture)
            : this(name,texture,null, FrameBufferClear.Color)
        {
        }

        public FrameBufferObjectProxy(string name, ITexture texture, IDepthBuffer depthBuffer, FrameBufferClear clearFlags)
            : base(name)
        {
            this.textures = new List<ITexture>(1);
            this.textures.Add(texture);
            this.DepthBuffer = depthBuffer;
            this.ClearFlags = clearFlags;
            ValidateBufferFormats();
        }
        #endregion

        #region Public interface
        public void Enable(IRenderPanel panel)
        {
            throw new NotImplementedException("Proxy objects do not have behaviors");
        }

        public void Disable(IRenderPanel panel)
        {
            throw new NotImplementedException("Proxy objects do not have behaviors");
        }
        #endregion

        #region Implementation
        private void ValidateBufferFormats()
        {
            if (this.textures == null || this.textures.Count < 1)
                throw new ArgumentNullException("At least one texture must be specified for a FrameBufferObject");
            if (this.textures.Count > 1)
            {
                bool first = true;
                ITexture textureToCompare = null;
                foreach (ITexture texture in textures)
                {
                    if (first)
                        textureToCompare = texture;
                    else
                        if (!textureToCompare.FormatsEqual(texture))
                        {
                            throw new ArgumentException("All texture must be the same format and size for a FrameBufferObject");
                        }
                }
            }
        }
        #endregion

        #region Member variables
        private IList<ITexture> textures;
        #endregion
    }
}
